package cn.zhc.com.utils;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import rx.Observable;
import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;

/**
 * Created by Zhou HongChun on 2017/3/3.
 */

public class UtilsFile {
    /**
     * 获取自定义APP缓存文件通用存放目录
     * @param context
     * @param mDirectoryName 文件目录名
     * @return
     */
    public static File getFileByDirectoryName(Context context, String mDirectoryName) {
        String cachePath;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            cachePath = context.getExternalCacheDir().getPath();
        } else {
            cachePath = context.getCacheDir().getPath();
        }
        File dir = new File(cachePath + File.separator + mDirectoryName);
        if (!dir.exists()){
            dir.mkdirs();
        }
        return dir;
    }


    /**
     * https://github.com/Curzibn/Luban
     * 压缩图片工具类
     */
    public static void compressImageFile(Context context,List<String> path, OnCompressListener listener) {
        Luban.with(context)
                .load(path)  // 传人要压缩的图片列表
                .setTargetDir(getFileByDirectoryName(context,UtilsOther.getAPPName(context)).getAbsolutePath())
                .setCompressListener(listener)
                .launch(); //启动压缩
    }

    /**
     * https://github.com/Curzibn/Luban
     * 压缩图片工具类
     */
    public static void compressImageFile(Context context,String path, OnCompressListener listener) {
        Luban.with(context)
                .load(path)  // 传人要压缩的图片列表
                .setTargetDir(getFileByDirectoryName(context,UtilsOther.getAPPName(context)).getAbsolutePath())
                .setCompressListener(listener)
                .launch(); //启动压缩
    }
    /**
     * https://github.com/Curzibn/Luban
     * 压缩图片工具类
     */
    public static void compressToFile(Context context,String path, OnCompressListener listener) {
        Luban.with(context)
                .load(path)  // 传人要压缩的图片列表
                .setTargetDir(getFileByDirectoryName(context,UtilsOther.getAPPName(context)).getAbsolutePath())
                .setCompressListener(listener)
                .launch(); //启动压缩
    }


    /**
     * 重命名文件,注意重命名是默认删除已存在的和新文件名相同的文件
     * 注意：重命名成功之后请使用文件的名字就是新的名字了
     * @param  newFileName 如 photo.jpg
     */
    public boolean rename(String absolutePath,String newFileName){
        File oldFile = new File(absolutePath);
        File newFile = new File(oldFile.getParent() + File.separator + newFileName);
        if (newFile.exists() && newFile.isFile()){
            newFile.delete();
        }
        boolean isSuccess = oldFile.renameTo(newFile);
        oldFile.delete();
        return isSuccess;
    }
    /**
     * 格式化单位，具有四舍五入的功能
     *
     * @param size 数据源
     * @param unit 进制，eg：1024
     * @return 格式化数据
     */
    public static String getFormatSizeWithRound(double size, int unit) {

        double kiloByte = size;
        if (kiloByte < 1024) {
            return "0 M";
        }
//        BigDecimal.setScale()方法用于格式化小数点
//        setScale(1)表示保留一位小数，默认用四舍五入方式
//        setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位，如2.35会变成2.3
//        setScale(1,BigDecimal.ROUND_UP)进位处理，2.35变成2.4
//        setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入，2.35变成2.4
//        setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入，2.35变成2.3，如果是5则向下舍
        double megaByte = kiloByte / unit;
        if (megaByte <= 1) {
            BigDecimal kiloResult = new BigDecimal(kiloByte);
            return kiloResult.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + " KB";
        }

        double gigaByte = megaByte / unit;
        if (gigaByte <= 1) {
            BigDecimal megaResult = new BigDecimal(megaByte);
            return megaResult.setScale(2, BigDecimal.ROUND_HALF_UP)
                    .toPlainString() + " MB";
        }

        double teraBytes = gigaByte / unit;
        if (teraBytes <= 1) {
            BigDecimal gigaResult = new BigDecimal(gigaByte);
            return gigaResult.setScale(2, BigDecimal.ROUND_HALF_UP)
                    .toPlainString() + " GB";
        }
        BigDecimal lastResult = new BigDecimal(teraBytes);
        return lastResult.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()
                + " TB";

    }

    /**
     * 格式化单位，不具有四舍五入的功能
     * @param size
     * @param unit
     * @return
     */
    public static String getFormatSize(int size, int unit) {
//        0 一个数字：显示该位，缺失补0
//        # 一个数字：不包括 0 第一个#表示不能是0的数字，不是0的话，后面的#就和0的效果一样，如果是0，则这个占位就不显示出来，然后递归判断第二个#。
//        . 小数的分隔符的占位符
        //保留两位小数
        long unitKB = unit;
        long unitMB = unit * unit;
        long unitGB = unit * unit * unit;
        long unitTB = unit * unit * unit * unit;
        if (size < unit)
            return "0 MB";
        if (size < unit * unit)
            return new DecimalFormat("0.00").format((float) size / unitKB) + " KB";
        if (size < unit * unit * unit)
            return new DecimalFormat("0.00").format((float) size / unitMB) + " MB";
        if (size < unit * unit * unit * unit)
            return new DecimalFormat("0.00").format((float) size / unitGB) + " GB";
        return new DecimalFormat("0.00").format((float) size / unitTB) + " TB";

    }

    /**
     * 获取单个文件大小
     *
     * @param file
     * @return
     */
    public static long getFileSize(File file) {
        long size = 0;
        if (file.exists() && file.isFile()) {
            size = file.length();
        }
        return size;
    }

    /**
     * 计算目录下所有文件的大小
     * @param file
     * @return
     */
    public static long getDirectorySize(File file) {

        long size = 0;
        try {
            if (file.exists()) {
                File[] fileList = file.listFiles();
                for (File tempFile : fileList) {
                    if (tempFile.isDirectory()) {
                        size = size + getDirectorySize(tempFile);
                    } else {
                        size = size + getFileSize(tempFile);
                    }
                }
            }
        }catch (Exception e){

        }

        return size;
    }


    /**
     * 删除文件或者目录,通过递归
     */
    public static boolean deleteFile(File dir) {
        if (dir != null && dir.exists()) {
            if (dir.isDirectory()) {
                //如果是一个目录，1、需要先删除目录下面的所有文件和子目录，2、最后删除这个初始目录
                //1、需要先删除目录下面的所有文件和子目录,如果有一个子元素删除失败，就表示删除失败
                for (File children : dir.listFiles()) {
                    boolean success = deleteFile(children);
                    //这里可以继续优化，待待续，需要处理删除失败
                    if (!success) {
                        return false;
                    }
                }

            }
            //2、最后删除这个初始目录
            //只有初始的dir删除成功才表示删除成功，否则都是失败
            return dir.delete();
        }
        return true;
    }

    /**
     * @param zipFile 源zip文件
     * @param descDir 指定目录
     */
    public static void unZipFiles(String zipFile, String descDir) {
        if (TextUtils.isEmpty(zipFile) || TextUtils.isEmpty(descDir))
            return;
        File pathFile = new File(descDir);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }

        InputStream in = null;
        OutputStream out = null;
        try {
            ZipFile zip = new ZipFile(new File(zipFile));
            for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                String zipEntryName = entry.getName();
                in = zip.getInputStream(entry);
                String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");
                File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
                if (!file.exists()) {
                    file.mkdirs();
                }
                if (new File(outPath).isDirectory()) {
                    continue;
                }
                out = new FileOutputStream(outPath);
                byte[] buf1 = new byte[1024 * 1024];
                int len;
                while ((len = in.read(buf1)) > 0) {
                    out.write(buf1, 0, len);
                }
                in.close();
                out.close();

            }
//            EventBus.getDefault().post(new EventUnZip(true));
        } catch (IOException e) {
            e.printStackTrace();
//            EventBus.getDefault().post(new EventUnZip(false));
        } finally {
            try {
                if (in != null) {
                    in.close();
                    in = null;
                }
                if (out != null) {
                    out.close();
                    out = null;
                }
            } catch (IOException e) {

            }

        }

    }
}
